﻿using GalaSoft.MvvmLight;
using Project1.Model;
using HalconDotNet;
using System;
using System.Windows;
using System.Windows.Data;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Views;
using GalaSoft.MvvmLight.Messaging;
using CommonServiceLocator;
using CommonLib;
using Project1.EventCommand;
using ElementLib;
namespace Project1.ViewModel
{
    public class RegistViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        //private INavigationService _navigationService;
        private CoreModel core;
        private ComplexInfoModel combboxItemForInvalidPointsNum;
        private ObservableCollection<ComplexInfoModel> combboxListForInvalidPointsNum;
        private ComplexInfoModel combboxItemForEdgeWidth;
        private ObservableCollection<ComplexInfoModel> combboxListForEdgeWidth;
        private ComplexInfoModel combboxItemForPoint;
        private ObservableCollection<ComplexInfoModel> combboxListForPoint;
        private ComplexInfoModel combboxItemForPeakPoint;

        private ObservableCollection<ComplexInfoModel> drawShapeList;
        private ObservableCollection<ComplexInfoModel> combboxListForPeakPoint;
        private ObservableCollection<ComplexInfoModel> elementList;
        private ObservableCollection<ComplexInfoModel> valueList;
        private ObservableCollection<ComplexInfoModel> planList;
        private List<MeasurePlan> measurePlans;
        // PlanList
        private ComplexInfoModel drawShapeItem;
        private ComplexInfoModel planItem;
        private ComplexInfoModel valueItem;
        private ComplexInfoModel elementItem;
        //private Point currentPosition;
        //private string drawShape;
        //private readonly string notFound = "状态当前没有可以显示的元素";
        private bool drawMode = false;

        public delegate void GetPositionMethod(out HTuple row, out HTuple column);

        public void UpdateElementInfo(string mode, Output pe = null)
        {
            if (mode == ConstValue.EMPTY_ELEMLIST)
            {
                ElementList.Clear();
            }
            else if (mode == ConstValue.UPDATE_ELEMLIST)
            {
                if (pe == null) return;
                if (pe.Type == ConstValue.POINT)
                {
                    foreach (var p in pe.Ps())
                    {
                        ElementList.Add(new ComplexInfoModel() { ElementName = p.ToString() });
                    }

                }
                else if (pe.Type == ConstValue.CIRCLE)
                {
                    foreach (var c in pe.Cs())
                    {
                        ElementList.Add(new ComplexInfoModel() { ElementName = c.ToString() });
                    }

                }
                else if (pe.Type == ConstValue.LINE)
                {
                    foreach (var l in pe.Ls())
                    {
                        ElementList.Add(new ComplexInfoModel() { ElementName = l.ToString() });
                    }
                }
                else if (pe.Type == ConstValue.DISTANCE)
                {
                    foreach (var dist in pe.Distances())
                    {
                        valueList.Add(new ComplexInfoModel() { ElementName = "" + dist });
                    }
                }


            }
        }


        private void Init()
        {
            combboxItemForInvalidPointsNum = new ComplexInfoModel();
            combboxListForInvalidPointsNum = new ObservableCollection<ComplexInfoModel>();
            combboxItemForPoint = new ComplexInfoModel();
            combboxListForPoint = new ObservableCollection<ComplexInfoModel>();
            combboxItemForPeakPoint = new ComplexInfoModel();
            combboxListForPeakPoint = new ObservableCollection<ComplexInfoModel>();
            combboxItemForEdgeWidth = new ComplexInfoModel();
            combboxListForEdgeWidth = new ObservableCollection<ComplexInfoModel>();
            elementItem = new ComplexInfoModel();
            elementList = new ObservableCollection<ComplexInfoModel>();



            drawShapeList = new ObservableCollection<ComplexInfoModel>();
            drawShapeItem = new ComplexInfoModel();
            valueList = new ObservableCollection<ComplexInfoModel>();
            valueItem = new ComplexInfoModel();
            planList = new ObservableCollection<ComplexInfoModel>();
            planItem = new ComplexInfoModel();
            DispPlanList();
            RefreshDrawShapeWindows();
            core.SetUpdateFunc(DispPlanList);
            core.SetUpdateFunc(UpdateElementInfo);
            GeneratePlanList();
            GenerateCombbox1();
            GenerateCombbox_EdgeWidth();
            GenerateCombbox_Point();
            GenerateCombbox_PeakPoint();
        }

        public RegistViewModel()
        {

            //_navigationService = navigationService;
            core = new CoreModel(null);
            Init();
            Messenger.Default.Register<string>(this, "Draw", ShowReceiveInfo);
            Messenger.Default.Register<HWindowControlWPF>(this, "BindWindow", BindWindow);
            Messenger.Default.Register<int>(this, ConstValue.MOUSEEVENT, OnMouseEvent);
            Messenger.Default.Register<double>(this, "Zoom", OnZoom);
            Messenger.Default.Register<Action>(this, "Menu", OnMenu);

            //Messenger.Default.Register<int>(this, "MeasureType", InitDefaultName);
        }

        private void OnMenu(Action act)
        {
            if (drawMode == false)
            {
                act.Invoke();
                MessageBox.Show("1");
            }
        }
        private void OnZoom(double scaleNum)
        {
            core.ImageZoom(scaleNum);
        }
        private void OnMouseEvent(int eventNum)
        {

            switch (eventNum)
            {
                case ConstValue.MouseDown2:
                    core.DrawObject(DrawShapeItem.ElementName);
                    break;
                case ConstValue.MouseDown:
                    core.FindROI();
                    break;
                case ConstValue.MouseMove:
                    if (core.Pressed == true) core.MoveSupportLine();
                    break;
                case ConstValue.MouseUp:
                    core.ApplySupLineChange();
                    break;
                case ConstValue.Adapt:
                    core.AdaptWindow();
                    break;
                default:
                    break;
            }
        }
        private void BindWindow(HWindowControlWPF windowControlWPF)
        {
            if (windowControlWPF.HalconWindow != null)
            {

                core.SetWindowHandle(windowControlWPF.HalconWindow);
            }
        }



        public void Load_Plan(object obj)
        {

            bool loadFlag = false;
            if (planItem == null)
            {
                MessageBox.Show("计划为空！", "提示", MessageBoxButton.OK);
                return;
            }
            ElementList.Clear();
            foreach (var item in measurePlans)
            {
                if (planItem.ElementName == item.PlanName)
                {
                    core.SetMeasurePlan(item);
                    foreach (var iep in item.IEPS)
                    {
                        ElementList.Add(new ComplexInfoModel() { ElementName = iep.Name });
                    }
                    foreach (var icm in item.ICMS)
                    {
                        ElementList.Add(new ComplexInfoModel() { ElementName = icm.Name });
                    }
                    loadFlag = true;
                    break;
                }
            }
            if (loadFlag == false)
            {
                MessageBox.Show("加载失败!");
            }
        }
        public void DispPlanList()
        {
            PlanList.Clear();
            //@"D:\Documents\Desktop"
            measurePlans = MeasurePlan.LoadMeasure(ConstValue.DEFAULT_MEASUREPLAN_PATH);
            //@"D:\Documents\Desktop\test"
            foreach (var item in measurePlans)
            {
                PlanList.Add(new ComplexInfoModel() { ElementName = item.PlanName });
            }
        }
        public void GeneratePlanList()
        {
            // PlanList.Add(new ComplexInfoModel() { ElementName = "测试" });
            //  ElementList.Add(new ComplexInfoModel() { ElementName = notFound });
            //  ValueList.Add(new ComplexInfoModel() { ElementName = notFound });
        }
        public void GenerateCombbox1()
        {
            combboxListForInvalidPointsNum.Clear();
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "0", Text = "0" });
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "1", Text = "1" });
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "2", Text = "2" });
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "3", Text = "3" });
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "4", Text = "4" });
            combboxListForInvalidPointsNum.Add(new ComplexInfoModel() { Key = "5", Text = "5" });
        }

        public void GenerateCombbox_Point()
        {
            combboxListForPoint.Clear();
            combboxListForPoint.Add(new ComplexInfoModel() { Key = "0", Text = "明->暗" });
            combboxListForPoint.Add(new ComplexInfoModel() { Key = "1", Text = "暗->明" });
        }
        public void GenerateCombbox_EdgeWidth()
        {
            combboxListForEdgeWidth.Clear();
            combboxListForEdgeWidth.Add(new ComplexInfoModel() { Key = "0", Text = "1.00" });
            combboxListForEdgeWidth.Add(new ComplexInfoModel() { Key = "1", Text = "2.00" });
            combboxListForEdgeWidth.Add(new ComplexInfoModel() { Key = "2", Text = "3.00" });
            combboxListForEdgeWidth.Add(new ComplexInfoModel() { Key = "3", Text = "4.00" });
            combboxListForEdgeWidth.Add(new ComplexInfoModel() { Key = "4", Text = "5.00" });
        }

        public void GenerateCombbox_PeakPoint()
        {
            combboxListForPeakPoint.Clear();
            combboxListForPeakPoint.Add(new ComplexInfoModel() { Key = "0", Text = "最大" });
            combboxListForPeakPoint.Add(new ComplexInfoModel() { Key = "1", Text = "最小" });
        }


        public ObservableCollection<ComplexInfoModel> DrawShapeList
        {
            get { return drawShapeList; }
            set
            {
                drawShapeList = value;
                RaisePropertyChanged(() => drawShapeList);
            }
        }

        public ComplexInfoModel DrawShapeItem
        {
            get { return drawShapeItem; }
            set
            {
                drawShapeItem = value;
                RaisePropertyChanged(() => DrawShapeItem);

            }
        }
        public ObservableCollection<ComplexInfoModel> ValueList
        {
            get { return valueList; }
            set { valueList = value; RaisePropertyChanged(() => ValueList); }
        }

        public ComplexInfoModel ValueItem
        {
            get { return valueItem; }
            set { valueItem = value; RaisePropertyChanged(() => ValueItem); }
        }
        public ObservableCollection<ComplexInfoModel> ElementList
        {
            get { return elementList; }
            set { elementList = value; RaisePropertyChanged(() => ElementList); }
        }

        public ComplexInfoModel ElementItem
        {
            get { return elementItem; }
            set { elementItem = value; RaisePropertyChanged(() => ElementItem); }
        }


        public ComplexInfoModel CombboxItemForPeakPoint
        {
            get { return combboxItemForPeakPoint; }
            set { combboxItemForPeakPoint = value; RaisePropertyChanged(() => CombboxItemForPeakPoint); }
        }

        public ObservableCollection<ComplexInfoModel> CombboxListForPeakPoint
        {
            get { return combboxListForPeakPoint; }
            set { combboxListForPeakPoint = value; RaisePropertyChanged(() => CombboxListForPeakPoint); }
        }

        public ComplexInfoModel CombboxItemForInvalidPointsNum
        {
            get { return combboxItemForInvalidPointsNum; }
            set { combboxItemForInvalidPointsNum = value; RaisePropertyChanged(() => CombboxItemForInvalidPointsNum); }
        }

        public ObservableCollection<ComplexInfoModel> CombboxListForInvalidPointsNum
        {
            get { return combboxListForInvalidPointsNum; }
            set { combboxListForInvalidPointsNum = value; RaisePropertyChanged(() => CombboxListForInvalidPointsNum); }
        }

        public ComplexInfoModel CombboxItemForEdgeWidth
        {
            get { return combboxItemForEdgeWidth; }
            set { combboxItemForEdgeWidth = value; RaisePropertyChanged(() => CombboxItemForEdgeWidth); }

        }

        public ObservableCollection<ComplexInfoModel> CombboxListForEdgeWidth
        {
            get { return combboxListForEdgeWidth; }
            set { combboxListForEdgeWidth = value; RaisePropertyChanged(() => CombboxListForEdgeWidth); }
        }
        public ComplexInfoModel CombboxItemForPoint
        {
            get { return combboxItemForPoint; }
            set { combboxItemForPoint = value; RaisePropertyChanged(() => CombboxItemForPoint); }
        }

        public ObservableCollection<ComplexInfoModel> CombboxListForPoint
        {
            get { return combboxListForPoint; }
            set { combboxListForPoint = value; RaisePropertyChanged(() => CombboxListForPoint); }
        }

        public ObservableCollection<ComplexInfoModel> PlanList
        {
            get { return planList; }
            set { planList = value; RaisePropertyChanged(() => PlanList); }
        }

        public ComplexInfoModel PlanItem
        {
            get { return planItem; }
            set { planItem = value; RaisePropertyChanged(() => PlanItem); }
        }
        public void Detect_Circle(object parameter)
        {
            core.DetectCircle();
            RefreshElementWindows(core);
        }

        public void Save_MeasurePlan(object parameter)
        {
            core.Save_MeasurePlan();
        }
        public void Apply_Changes(object parameter)
        {
            core.Apply("add"); //正式添加元素
            core.callBack();
        }
        public void Detect_PeakPoint(object parameter)
        {
            HTuple hv_Mode = "neighbor";
            if (CombboxItemForPeakPoint.Text == "")
            {
                MessageBox.Show("请选择优先级");
                return;
            }
            else if (CombboxItemForPeakPoint.Text == "最小")
            {
                hv_Mode = new HTuple("longest");
            }
            else if (CombboxItemForPeakPoint.Text == "最大")
            {
                hv_Mode = new HTuple("neighbor");
            }
            if (core.ItemName == "")
            {
                MessageBox.Show("没有输入要素的名字");
                return;
            }
            core.DetectPeakPoint(hv_Mode);
            RefreshElementWindows(core);
        }
        public void OnWindowClose()
        {
            HOperatorSet.CloseWindow(CORE.windowHandle);
        }
        public void Detect_Point(object parameter)
        {
            HTuple hv_Mode = "positive";
            if (combboxItemForPoint.Text == "")
            {
                MessageBox.Show("请选择边缘方向");
                return;
            }
            else if (combboxItemForPoint.Text == "明->暗")
            {
                hv_Mode = new HTuple("negative");
            }
            else if (combboxItemForPoint.Text == "暗->明")
            {
                hv_Mode = new HTuple("positive");
            }
            if (core.ItemName == "")
            {
                MessageBox.Show("没有输入要素的名字");
                return;
            }
            core.DetectPoint(hv_Mode);
            RefreshElementWindows(core);
        }
        public void Detect_Line(object parameter)
        {

            core.DetectLine();
            RefreshElementWindows(core);

        }

        public void Specific_Detect(object parameter)
        {

            core.DetectLine();
            RefreshElementWindows(core);
        }


        public void RefreshDrawShapeWindows()
        {
            DrawShapeList.Add(new ComplexInfoModel() { ElementName = ConstValue.DRAW_RECTANGLE1 });
            DrawShapeList.Add(new ComplexInfoModel() { ElementName = ConstValue.DRAW_CIRCLE });
            DrawShapeList.Add(new ComplexInfoModel() { ElementName = ConstValue.DRAW_RECTANGLE2 });
            DrawShapeList.Add(new ComplexInfoModel() { ElementName = ConstValue.DRAW_ELLIPSE });
            DrawShapeList.Add(new ComplexInfoModel() { ElementName = ConstValue.DRAW_LINE });

        }
        public void RefreshElementWindows(CoreModel core)
        {
            ElementList.Clear();
            ValueList.Clear();
            foreach (var item in core.Circle)
            {
                ElementList.Add(new ComplexInfoModel() { ElementName = item.C.ToString() });
            }
            foreach (var item in core.Points)
            {
                ElementList.Add(new ComplexInfoModel() { ElementName = item.P.ToString() });
            }
            foreach (var item in core.Lines)
            {
                ElementList.Add(new ComplexInfoModel() { ElementName = item.L.ToString() });
            }
            foreach (var item in core.Distances)
            {
                ValueList.Add(new ComplexInfoModel() { ElementName = item.ToString() });
            }

            foreach (var item in core.Angles)
            {
                ValueList.Add(new ComplexInfoModel() { ElementName = item.ToString() });
            }

            if (ElementList.Count == 0)
            {
                // ElementList.Add(new ComplexInfoModel() { ElementName = notFound });
                // ValueList.Add(new ComplexInfoModel() { ElementName = notFound });
            }
        }
        private void OnOpenImage(object obj)
        {
            HWindowControlWPF windowControlWPF = ((ExCommandParameter)obj).Parameter as HWindowControlWPF;
            // ComboBox cbStretch = ((ExCommandParameter)obj).Sender as ComboBox;
            // Viewbox sampleViewBox = ((ExCommandParameter)obj).Parameter as Viewbox;

            if (windowControlWPF.HalconWindow != null)
            {

                core.SetWindowHandle(windowControlWPF.HalconWindow);
                core.OpenImage();
            }

        }


        public void Regist_Model(object obj)
        {
            core.RegistModel();
        }
        public void Matching_Model(object obj)
        {
            core.Matching();
        }
        public void Extend_Detect(object obj)
        {
            core.ExtendDetect();
        }
        public void Disp_Adapt(object obj)
        {
            core.AdaptWindow();
        }
        public void Zoom_Up(object obj)
        {
            core.ImageZoom(1.5, true);
        }

        public void Zoom_Down(object obj)
        {
            core.ImageZoom(0.5, true);
        }

        public void Load_Model(object obj)
        {
            HWindowControlWPF windowControlWPF = ((ExCommandParameter)obj).Parameter as HWindowControlWPF;
            if (windowControlWPF.HalconWindow != null)
            {
                core.SetWindowHandle(windowControlWPF.HalconWindow);
                core.LoadModel();
            }
            else
            {
                MessageBox.Show("异常");
            }

        }

        public void Extract_Image(object obj)
        {
            core.ExtractModel();
        }
        private void Init_Window(object obj)
        {
            HWindowControlWPF windowControlWPF = ((ExCommandParameter)obj).Parameter as HWindowControlWPF;
            if (windowControlWPF.HalconID != null)
            {
                core.SetWindowHandle(windowControlWPF.HalconWindow);
                Utils.hv_ExpDefaultWinHandle = windowControlWPF.HalconWindow;
                ConstValue.AddwindowHandle(windowControlWPF.HalconWindow);
            }

        }

        public void Switch_Component(object obj)
        {
            var navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
            string msg = (string)obj;
            if (msg == "circle")
            {
                navigationService.NavigateTo("UCC");
            }
            else if (msg == "line")
            {
                navigationService.NavigateTo("UCL");
            }
            else if (msg == "point")
            {
                navigationService.NavigateTo("UCP");
            }
            else if (msg == "peakPoint")
            {
                navigationService.NavigateTo("UCPP");
            }
        }


        public MyCommand LoadPlan
        {
            get { return new MyCommand(Load_Plan); }
        }
        public MyCommand SwitchComponent
        {
            get { return new MyCommand(Switch_Component); }
        }
        public MyCommand ExtractImage
        {
            get { return new MyCommand(Extract_Image); }
        }
        public MyCommand LoadModel
        {
            get { return new MyCommand(Load_Model); }
        }
        public MyCommand Matching
        {
            get { return new MyCommand(Matching_Model); }
        }
        public MyCommand ExtendDetect
        {
            get { return new MyCommand(Extend_Detect); }
        }
        public MyCommand DetectLine
        {
            get { return new MyCommand(Detect_Line); }
        }
        public MyCommand SpecificDetect
        {
            get { return new MyCommand(Specific_Detect); }
        }
        public MyCommand DetectCircle
        {
            get { return new MyCommand(Detect_Circle); }
        }

        public MyCommand RegistModel
        {
            get { return new MyCommand(Regist_Model); }
        }
        public MyCommand DispAdapt
        {
            get { return new MyCommand(Disp_Adapt); }
        }
        public MyCommand ZoomUp
        {
            get { return new MyCommand(Zoom_Up); }
        }

        public MyCommand ZoomDown
        {
            get { return new MyCommand(Zoom_Down); }
        }

        public MyCommand SavePlan
        {
            get { return new MyCommand(Save_MeasurePlan); }
        }
        public MyCommand ApplyChanges
        {
            get { return new MyCommand(Apply_Changes); }
        }
        public MyCommand DetectPeakPoint
        {
            get { return new MyCommand(Detect_PeakPoint); }
        }

        public MyCommand DetectPoint
        {
            get { return new MyCommand(Detect_Point); }
        }
        public MyCommand OpenImage
        {
            get { return new MyCommand(OnOpenImage); }
        }
        public MyCommand InitWindow
        {
            get { return new MyCommand(Init_Window); }
        }// = new DelegateCommand(new Action<object>(StretchSelectionChanged));
         //{ ExecuteActionObj = new Action<object>(StretchSelectionChanged) };



        public MyCommand BackToSelection
        {
            get { return new MyCommand(BackTo_Selection); }
        }

        private void BackTo_Selection(object obj)
        {
            core.callBack();
        }


        private void InitDefaultName(int msg)
        {
            //core.GetDefaultName(msg);
        }
        private void ShowReceiveInfo(string msg)
        {
            //MessageBox.Show(msg);
            if (msg == "clear")
            {
                core.ClearAllObjects(true);
                core.SetDrawMode(true);
            }

            else
            {
                core.DrawObject(msg);
            }


        }
        public CoreViewModel ViewPagePoint
        {
            get;
            set;
        }


        public CoreModel CORE
        {
            get
            {
                return core;
            }
            set
            {
                core = value;
                RaisePropertyChanged(() => CORE);
            }
        }
    }
}
